home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / other / dopus412-gpl / program / main7.c < prev    next >
C/C++ Source or Header  |  2000-02-28  |  13KB  |  511 lines

  1. /*
  2.  
  3. Directory Opus 4
  4. Original GPL release version 4.12
  5. Copyright 1993-2000 Jonathan Potter
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. All users of Directory Opus 4 (including versions distributed
  22. under the GPL) are entitled to upgrade to the latest version of
  23. Directory Opus version 5 at a reduced price. Please see
  24. http://www.gpsoft.com.au for more information.
  25.  
  26. The release of Directory Opus 4 under the GPL in NO WAY affects
  27. the existing commercial status of Directory Opus 5.
  28.  
  29. */
  30.  
  31. #include "DOpus.h"
  32. #include "music.h"
  33.  
  34. showpic(fullname,np)
  35. char *fullname;
  36. int np;
  37. {
  38.     int res,a;
  39.     char buf[256];
  40.  
  41.     if (checkexec(fullname) && checkisfont(fullname,buf))
  42.         return((showfont(buf,atoi(BaseName(fullname)),np)));
  43.  
  44.     a=strlen(fullname);
  45.     if (a>5 && LStrCmpI(&fullname[a-5],".info")==0) {
  46.         if ((res=readicon(fullname,np))==0) return(1);
  47.         if (res==-2) {
  48.             doerror(IoErr());
  49.             return(0);
  50.         }
  51.         if (res==-3) {
  52.             dostatustext(globstring[STR_NO_CHIP_FOR_ICON]);
  53.             return(0);
  54.         }
  55.         return(res);
  56.     }
  57.  
  58.     if (!(res=LoadPic(fullname))) doerror(IoErr());
  59.     else if (res==IFFERR_NOTILBM) dostatustext(globstring[STR_FILE_NOT_ILBM]);
  60.     else if (res==IFFERR_BADIFF) dostatustext(globstring[STR_ERROR_IN_IFF]);
  61.     else if (res==IFFERR_NOMEMORY) dostatustext(globstring[STR_NO_CHIP_FOR_PICTURE]);
  62.     else if (res==IFFERR_BADMODE) dostatustext(globstring[STR_SCREEN_MODE_UNAVAILABLE]);
  63.     else if (res==IFFERR_NOSCREEN) dostatustext(globstring[STR_UNABLE_TO_OPEN_WINDOW]);
  64.     if (res==-1) return(-1);
  65.     else if (!res || res<-1) return(0);
  66.     return(1);
  67. }
  68.  
  69. checkisfont(pathname,fontname)
  70. char *pathname,*fontname;
  71. {
  72.     int a;
  73.     char fontsize[33],fontpath[256],*ptr;
  74.  
  75.     strcpy(fontpath,pathname);
  76.     if (ptr=BaseName(fontpath)) {
  77.         strcpy(fontsize,ptr);
  78.         *(--ptr)=0;
  79.         if (ptr=BaseName(fontpath)) {
  80.             for (a=0;;a++) {
  81.                 if (!(isdigit(fontsize[a]))) break;
  82.             }
  83.             if (!fontsize[a]) {
  84.                 strcat(fontpath,".font");
  85.                 if (CheckExist(fontpath,NULL)) {
  86.                     strcpy(fontname,fontpath);
  87.                     return(1);
  88.                 }
  89.             }
  90.         }
  91.     }
  92.     return(0);
  93. }
  94.  
  95. readicon(name,np)
  96. char *name;
  97. int np;
  98. {
  99.     struct DiskObject *dobj;
  100.     struct Gadget *gad;
  101.     struct Image *icon_image[2];
  102.     UWORD coltab[16];
  103.     int fred,ret,width,height,x,y,x1,y1,imagenum,depth;
  104.  
  105.     if (!IconBase) return(0);
  106.  
  107.     name[(strlen(name)-5)]=0;
  108.     if (!(dobj=GetDiskObject(name))) return(-2);
  109.  
  110.     gad=(struct Gadget *)&(dobj->do_Gadget);
  111.  
  112.     icon_image[0]=(struct Image *)gad->GadgetRender;
  113.     depth=icon_image[0]->Depth;
  114.     if (depth>4) depth=4;
  115.  
  116.     if (!icon_image[0] || !(setupfontdisplay(depth,coltab))) {
  117.         FreeDiskObject(dobj);
  118.         return(-3);
  119.     }
  120.  
  121.     if (gad->Flags&GADGHIMAGE) icon_image[1]=(struct Image *)gad->SelectRender;
  122.     else icon_image[1]=icon_image[0];
  123.  
  124.     for (x=0;x<2;x++) icon_image[x]->NextImage=NULL;
  125.  
  126.     imagenum=0;
  127.  
  128.     ScreenToFront(fontscreen);
  129.     ActivateWindow(fontwindow);
  130.  
  131.     width=fontscreen->Width;
  132.     height=fontscreen->Height;
  133.  
  134.     DrawImage(font_rp,icon_image[0],
  135.         ((width-icon_image[0]->Width)/2),
  136.         ((height-icon_image[0]->Height)/2));
  137.  
  138.     FadeRGB4(fontscreen,coltab,(1<<depth),1,config->fadetime);
  139.     show_global_icon=dobj;
  140.     show_global_icon_name=BaseName(name);
  141.  
  142.     FOREVER {
  143.         if ((fred=WaitForMouseClick(2,fontwindow))==-2) {
  144.             imagenum=1-imagenum;
  145.             x=(width-icon_image[imagenum]->Width)/2;
  146.             y=(height-icon_image[imagenum]->Height)/2;
  147.             x1=x+icon_image[imagenum]->Width;
  148.             y1=y+icon_image[imagenum]->Height;
  149.             DrawImage(font_rp,icon_image[imagenum],x,y);
  150.             drawrecaround(font_rp,0,0,x,y,x1,y1,width,height);
  151.         }
  152.         else {
  153.             if (fred==0 || fred==-3) ret=TRUE;
  154.             else ret=-1;
  155.             break;
  156.         }
  157.     }
  158.     show_global_icon=NULL;
  159.     if (fred!=-3) FadeRGB4(fontscreen,coltab,(1<<depth),-1,config->fadetime);
  160. cleanicon:
  161.     FreeDiskObject(dobj);
  162.     cleanup_fontdisplay();
  163.     return(ret);
  164. }
  165.  
  166. void drawrecaround(r,l,t,x,y,x1,y1,width,height)
  167. struct RastPort *r;
  168. int l,t,x,y,x1,y1,width,height;
  169. {
  170.     char o;
  171.  
  172.     o=r->FgPen; SetAPen(r,0);
  173.     if (x>0) RectFill(r,l,t,l+x-1,t+height-1);
  174.     if (y>0) RectFill(r,l,t,l+width-1,t+y-1);
  175.     if (x1<l+width) RectFill(r,l+x1,t,l+width-1,t+height-1);
  176.     if (y1<t+height) RectFill(r,l,t+y1,l+width-1,t+height-1);
  177.     SetAPen(r,o);
  178. }
  179.  
  180. doplay8svx(fname,loop)
  181. char *fname;
  182. int loop;
  183. {
  184.     Voice8Header *pvoice8header=NULL;
  185.     UBYTE *p8data;
  186.     ULONG speed,size,class,rsize,chan=0;
  187.     USHORT code;
  188.     char *psample,*ry,*compressbuf;
  189.     ChunkHeader *p8chunk;
  190.     int a,b,stereo,*vxcheck,finish,playsize;
  191.     struct IOAudio *audioptr[2];
  192.     UBYTE *playdata[2];
  193.     static UBYTE audiochannels[2][4]={{9,1,8,4},{6,2,4,8}};
  194.  
  195.     for (a=0;a<2;a++) {
  196.         audio_port[a]=NULL;
  197.         audio_req1[a]=audio_req2[a]=NULL;
  198.     }
  199.     audiodata=NULL;
  200.     status_flags&=~STATUS_AUDIOLED;
  201.  
  202.     if ((a=readfile(fname,&audiodata,(int *)&audio_size))) {
  203.         if (a==-1) return(0);
  204.         return(-2);
  205.     }
  206.     vxcheck=(int *)audiodata;
  207.     if (audio_size<12 || vxcheck[0]!=ID_FORM || vxcheck[2]!=ID_8SVX) {
  208.         size=audio_size;
  209.         p8data=audiodata;
  210.         psample=p8data;
  211.     }
  212.     else {
  213.         p8data=audiodata+12;
  214.         size=0;
  215.         while (p8data<audiodata+vxcheck[1]) {
  216.             p8chunk=(ChunkHeader *)p8data;
  217.             p8data+=sizeof(ChunkHeader);
  218.             switch (p8chunk->ckID) {
  219.                 case ID_VHDR:
  220.                     pvoice8header=(Voice8Header *)p8data;
  221.                     break;
  222.                 case ID_BODY:
  223.                     psample=p8data;
  224.                     size=p8chunk->ckSize;
  225.                     break;
  226.                 case ID_CHAN:
  227.                     CopyMem((char *)p8data,(char *)&chan,4);
  228.                     break;
  229.             }
  230.             p8data+=p8chunk->ckSize;
  231.             if (p8chunk->ckSize&1) ++p8data;
  232.         }
  233.     }
  234.  
  235.     if (size>vxcheck[1]) {
  236.         size/=2; chan=0;
  237.     }
  238.  
  239.     if (pvoice8header) {
  240.         if (pvoice8header->sCompression==1) {
  241.             size-=2;
  242.             if (!(compressbuf=LAllocRemember(&audio_key,size*2,MEMF_CLEAR))) return(-2);
  243.             DUnpack(psample+2,size,compressbuf,psample[1]);
  244.             psample=compressbuf; size*=2;
  245.         }
  246.         speed=data_colorclock/pvoice8header->samplesPerSec;
  247.     }
  248.     else speed=data_colorclock/10000;
  249.  
  250.     if (chan==6) {
  251.         size/=2;
  252.         stereo=size;
  253.     }
  254.     else stereo=0;
  255.  
  256.     for (a=0;a<2;a++) {
  257.         if (!(audio_req1[a]=LAllocRemember(&audio_key,sizeof(struct IOAudio),MEMF_CLEAR)) ||
  258.             !(audio_req2[a]=LAllocRemember(&audio_key,sizeof(struct IOAudio),MEMF_CLEAR)) ||
  259.             !(audio_port[a]=LCreatePort(NULL,0))) return(-2);
  260.     }
  261.  
  262.     for (a=0;a<2;a++) {
  263.         audio_req1[a]->ioa_Request.io_Message.mn_ReplyPort=audio_port[a];
  264.         audio_req1[a]->ioa_Request.io_Message.mn_Node.ln_Pri=75;
  265.         audio_req1[a]->ioa_Data=audiochannels[a];
  266.         audio_req1[a]->ioa_Length=sizeof(audiochannels[a]);
  267.         if (OpenDevice("audio.device",0,(struct IORequest *)audio_req1[a],0)) return(-6);
  268.     }
  269.  
  270.     playsize=(size<25600)?size:25600;
  271.     for (a=0;a<2;a++) {
  272.         if (!(playdata[a]=LAllocRemember(&audio_key,playsize,MEMF_CHIP|MEMF_CLEAR)))
  273.             return(-2);
  274.     }
  275.  
  276.     ry=psample;
  277.     for (a=0;a<2;a++) CopyMem(psample+(a*stereo),(char *)playdata[a],playsize);
  278.  
  279.     for (a=0;a<2;a++) {
  280.         audio_req1[a]->ioa_Request.io_Command=CMD_WRITE;
  281.         audio_req1[a]->ioa_Request.io_Flags=ADIOF_PERVOL;
  282.         audio_req1[a]->ioa_Volume=64;
  283.         audio_req1[a]->ioa_Period=(UWORD)speed;
  284.         audio_req1[a]->ioa_Cycles=1;
  285.         CopyMem((char *)audio_req1[a],(char *)audio_req2[a],sizeof(struct IOAudio));
  286.         audio_req1[a]->ioa_Data=(UBYTE *)playdata[a];
  287.         audio_req2[a]->ioa_Data=(UBYTE *)playdata[a]+12800;
  288.         audioptr[a]=audio_req2[a];
  289.     }
  290.     rsize=size;
  291.  
  292.     if (config->viewbits&VIEWBITS_FILTEROFF) {
  293.         if (filteroff()) status_flags|=STATUS_AUDIOLED;
  294.         else status_flags&=~STATUS_AUDIOLED;
  295.     }
  296.  
  297.     if (size<=25600) {
  298.         FOREVER {
  299.             for (b=0;b<2;b++) {
  300.                 audio_req1[b]->ioa_Length=size;
  301.                 BeginIO((struct IORequest *)audio_req1[b]);
  302.             }
  303.             a=0;
  304.             FOREVER {
  305.                 Wait(1<<audio_port[0]->mp_SigBit|1<<audio_port[1]->mp_SigBit|1<<Window->UserPort->mp_SigBit);
  306.                 while (getintuimsg()) {
  307.                     class=IMsg->Class; code=IMsg->Code;
  308.                     ReplyMsg((struct Message *)IMsg);
  309.                     if (class==IDCMP_MOUSEBUTTONS) {
  310.                         if (code==MENUDOWN) a=-1;
  311.                         else if (code==SELECTDOWN) a=-2;
  312.                     }
  313.                     else if (class==IDCMP_RAWKEY) {
  314.                         if (code==0x45) a=-1;
  315.                         else if (code==0x10 || code==0x32) a=-2;
  316.                     }
  317.                     if (a<0) {
  318.                         if (a==-2) return(1);
  319.                         return(a);
  320.                     }
  321.                 }
  322.                 for (b=0;b<2;b++) if (GetMsg(audio_port[b])) ++a;
  323.                 if (a>=2) break;
  324.             }
  325.             if (!loop) return(1);
  326.         }
  327.     }
  328.     else {
  329.         finish=0;
  330.         FOREVER {
  331.             size=rsize;
  332.             psample=ry;
  333.             for (a=0;a<2;a++) {
  334.                 CopyMem(psample+(a*stereo),(char *)playdata[a],playsize);
  335.                 CopyMem((char *)audio_req1[a],(char *)audio_req2[a],sizeof(struct IOAudio));
  336.                 audio_req1[a]->ioa_Data=(UBYTE *)playdata[a];
  337.                 audio_req2[a]->ioa_Data=(UBYTE *)playdata[a]+12800;
  338.                 audio_req1[a]->ioa_Length=audio_req2[a]->ioa_Length=12800;
  339.                 audioptr[a]=audio_req2[a];
  340.             }
  341.             psample+=playsize;
  342.             size-=25600;
  343.             for (a=0;a<2;a++) BeginIO((struct IORequest *)audio_req1[a]);
  344.             for (a=0;a<2;a++) BeginIO((struct IORequest *)audio_req2[a]);
  345.             a=0;
  346.             FOREVER {
  347.                 while (getintuimsg()) {
  348.                     class=IMsg->Class; code=IMsg->Code;
  349.                     ReplyMsg((struct Message *)IMsg);
  350.                     if (class==IDCMP_MOUSEBUTTONS) {
  351.                         if (code==SELECTDOWN) return(1);
  352.                         if (code==MENUDOWN) return(-1);
  353.                     }
  354.                     else if (class==IDCMP_RAWKEY) {
  355.                         if (code==0x45) return(-1);
  356.                         else if (code==0x10 || code==0x32) return(1);
  357.                     }
  358.                 }
  359.                 for (b=0;b<2;b++) {
  360.                     if (GetMsg(audio_port[b]) && !(a&(1<<b))) {
  361.                         if (size>0) {
  362.                             if (audioptr[b]==audio_req1[b]) audioptr[b]=audio_req2[b];
  363.                             else audioptr[b]=audio_req1[b];
  364.                             audioptr[b]->ioa_Length=(size<12800)?size:12800;
  365.                             CopyMem(psample+(b*stereo),(char *)audioptr[b]->ioa_Data,audioptr[b]->ioa_Length);
  366.                         }
  367.                         a|=1<<b;
  368.                     }
  369.                 }
  370.                 if (a==3) {
  371.                     if (size<=0) {
  372.                         if (finish) {
  373.                             finish=0;
  374.                             break;
  375.                         }
  376.                         finish=1;
  377.                     }
  378.                     else {
  379.                         size-=audioptr[0]->ioa_Length;
  380.                         psample+=12800;
  381.                         for (b=0;b<2;b++) BeginIO((struct IORequest *)audioptr[b]);
  382.                     }
  383.                     a=0;
  384.                 }
  385.                 Wait(1<<audio_port[0]->mp_SigBit|1<<audio_port[1]->mp_SigBit|1<<Window->UserPort->mp_SigBit);
  386.             }
  387.             if (!loop) return(1);
  388.         }
  389.     }
  390. }
  391.  
  392. void kill8svx()
  393. {
  394.     int a;
  395.  
  396.     for (a=0;a<2;a++) {
  397.         if (audio_req2[a] && audio_req2[a]->ioa_Request.io_Device) {
  398.             audio_req2[a]->ioa_Request.io_Command=CMD_FLUSH;
  399.             DoIO((struct IORequest *)audio_req2[a]);
  400.         }
  401.         if (audio_req1[a] && audio_req1[a]->ioa_Request.io_Device) {
  402.             audio_req1[a]->ioa_Request.io_Command=CMD_FLUSH;
  403.             DoIO((struct IORequest *)audio_req1[a]);
  404.             CloseDevice((struct IORequest *)audio_req1[a]);
  405.         }
  406.         audio_req1[a]=NULL;
  407.         audio_req2[a]=NULL;
  408.     }
  409.     for (a=0;a<2;a++) {
  410.         if (audio_port[a]) {
  411.             while (GetMsg(audio_port[a]));
  412.             LDeletePort(audio_port[a]);
  413.             audio_port[a]=NULL;
  414.         }
  415.     }
  416.     if (audiodata && audio_size) FreeMem(audiodata,audio_size);
  417.     LFreeRemember(&audio_key);
  418.     audiodata=NULL;
  419.     if (status_flags&STATUS_AUDIOLED) {
  420.         filteron();
  421.         status_flags&=~STATUS_AUDIOLED;
  422.     }
  423. }
  424.  
  425. void handle8svxerror(res)
  426. int res;
  427. {
  428.     switch (res) {
  429.         case 0: doerror(IoErr()); break;
  430.         case -2: doerror(103); break;
  431.         case -3:
  432.         case -4: dostatustext(globstring[STR_ERROR_IN_IFF]); break;
  433.         case -6: dostatustext(globstring[STR_CANT_ALLOCATE_AUDIO]); break;
  434.     }
  435. }
  436.  
  437. playmod(name)
  438. char *name;
  439. {
  440.     int a;
  441.  
  442.     if ((a=PlayModule(name,1))) {
  443.         switch (a) {
  444.             case ML_NOMEM: doerror(103); break;
  445.             case ML_BADMOD:
  446.                 dostatustext(globstring[STR_NOT_ST_MOD]);
  447.                 break;
  448.             case ML_NOMOD: doerror(205); break;
  449.             default:
  450.                 doerror(0);
  451.                 break;
  452.         }
  453.         FlushModule();
  454.         return(0);
  455.     }
  456.     return(1);
  457. }
  458.  
  459. check_is_module(name)
  460. char *name;
  461. {
  462.     int a;
  463.  
  464.     if (MUSICBase) {
  465.         a=IsModule(name);
  466.         if (a>0 && a<100) return(1);
  467.     }
  468.     return(0);
  469. }
  470.  
  471. static char codetodelta[16]={-34,-21,-13,-8,-5,-3,-2,-1,0,1,2,3,5,8,13,21};
  472.  
  473. char DUnpack(source,n,dest,x)
  474. char *source;
  475. int n;
  476. char *dest,x;
  477. {
  478.     unsigned char d;
  479.     int i,lim;
  480.  
  481.     lim=n<<1;
  482.     for (i=0;i<lim;++i) {
  483.         d=source[i>>1];
  484.         if (i&1) d&=0xf;
  485.         else d>>=4;
  486.         x+=codetodelta[d];
  487.         dest[i]=x;
  488.     }
  489.     return(x);
  490. }
  491.  
  492. EnvoyPacket(device,action,action2,data,buffer)
  493. char *device;
  494. ULONG action,action2;
  495. UWORD data;
  496. APTR buffer;
  497. {
  498.     struct MsgPort *handler;
  499.     ULONG args[2];
  500.  
  501.     if (!(handler=(struct MsgPort *)DeviceProc(device))) return(-1);
  502.  
  503.     args[0]=data;
  504.     args[1]=(ULONG)buffer;
  505.     if (!(SendPacket(handler,action,args,2))) {
  506.         if (action2) return(!(SendPacket(handler,action2,args,2)));
  507.         return(1);
  508.     }
  509.     return(0);
  510. }
  511.